package com.topisv.tms.web.stock.instorage;

import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springside.modules.web.Servlets;

import com.topisv.tms.entity.JSONParam;
import com.topisv.tms.entity.QueryParamHolder;
import com.topisv.tms.entity.stock.instorage.InstorageBill;
import com.topisv.tms.entity.stock.instorage.InstorageCountItem;
import com.topisv.tms.entity.stock.instorage.InstorageLog;
import com.topisv.tms.entity.stock.instorage.InstorageUpDispatchSubTask;
import com.topisv.tms.entity.stock.instorage.InstorageUpDispatchTask;
import com.topisv.tms.entity.stock.instorage.InstorageUpSubTaskItem;
import com.topisv.tms.exception.ErrorCode;
import com.topisv.tms.exception.PaiUException;
import com.topisv.tms.repository.stock.instorage.InstorageBillDao;
import com.topisv.tms.repository.stock.instorage.InstorageLogDao;
import com.topisv.tms.repository.stock.instorage.InstorageUpDispatchTaskDao;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.stock.instorage.InstorageBillService;
import com.topisv.tms.service.stock.instorage.InstorageUpDispatchTaskService;
import com.topisv.tms.service.vo.PrinterStyleType;
import com.topisv.tms.service.work.WorkTaskService;
import com.topisv.tms.web.base.BaseDataTableController;

/**
 * 上架任务分配
 *  Date          Author       Version       Description
 * ----------------------------------------------------------
 *  2015-4-10      CC            1.0           Create
 */
@Controller
@RequestMapping(value = "/v2_instorageUpDispatch")
public class InstorageUpDispatchTaskController extends BaseDataTableController {
	private static final Logger logger = LoggerFactory.getLogger(InstorageUpDispatchTaskController.class);
	@Autowired
	private InstorageUpDispatchTaskService instorageUpDispatchTaskService;
	@Autowired
	private InstorageUpDispatchTaskDao instorageUpDispatchTaskDao;
	@Autowired
	private InstorageBillDao instorageBillDao; 
	@Autowired
	private InstorageBillService instorageBillService;
	@Autowired
	private InstorageLogDao instorageLogDao;
	
	@Autowired
    private WorkTaskService workTaskService;


	@RequestMapping("show")
	public String show(Model model) {
		fillSelectValue(model, null);
		return "instorage/instorageUpDispatchList";
	}

	@RequestMapping(value = "page", method = RequestMethod.POST)
	public void page(@RequestBody JSONParam[] paramJson, HttpServletRequest request, HttpServletResponse response) {
		try {
			// 客户端参数
			QueryParamHolder paramHolder = collectParam(paramJson, "_");
			// 特殊处理时间
			Map<String, Object> searchParams = paramHolder.getSearchParams();
			String fromTm = (String) searchParams.get("GTE_instorageBill.createTime");
			String toTm = (String) searchParams.get("LT_instorageBill.createTime");
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			if (!StringUtils.isBlank(fromTm)) {
				searchParams.put("GTE_instorageBill.createTime", sdf.parse(fromTm));
			}
			if (!StringUtils.isBlank(toTm)) {
				searchParams.put("LT_instorageBill.createTime", sdf.parse(toTm));
			}
			Page<InstorageUpDispatchTask> page = instorageUpDispatchTaskService.findDisPatchTask(paramHolder);
			// 封装查询结果
			response.getWriter().print(bulidJSON(page));
		} catch (Exception e) {
			log.error("error", e);
		}
	}

	/**
	 * 为上架分配任务
	 * @param request
	 * @param response
	 * @param model
	 * @return String
	 */
	@RequestMapping(value = "toUpTaskDispatchPage")
	public String toUpTaskListPage(ServletRequest request, HttpServletResponse response, Model model) {
		try {
			fillSelectValue(model, null);
			// 当前用户关联的商家列表
			ShiroUser curUser = getShiroUser();
			model.addAttribute("userType", curUser.userType);

			// 我的任务
			Map<String, Object> param_my = new HashMap<String, Object>();
			param_my.put("workerUuid", curUser.jobuuid);
			param_my.put("status", "1");
			List<InstorageUpDispatchTask> myTaskList = this.instorageUpDispatchTaskService.loadTaskByParam(param_my);
			model.addAttribute("myTaskList", myTaskList);

			// 如果是派友用户,初始化数据
			if ("paiu".equals(curUser.userType)) {

				Map<String, Object> params = Servlets.getParametersStartingWith(request, "_");
				String warehouseCode = (String) params.get("warehouseCode");
				String customerCode = (String) params.get("customerCode");

				// 未分配的拣货任务
				Map<String, Object> param = new HashMap<String, Object>();
				param.put("customerCodes", StringUtils.isBlank(customerCode) ? curUser.customers : customerCode);
				param.put("areagroups", StringUtils.isBlank(warehouseCode) ? curUser.areagroups : warehouseCode);
				param.put("status", "0"); // 任务状态 （0.创建任务 1:领取 2:完成
				List<InstorageUpDispatchTask> untakedTaskList = this.instorageUpDispatchTaskService.loadTaskByParam(param);
				model.addAttribute("untakedTaskList", untakedTaskList);
			}

		} catch (Exception e) {

			log.error("error", e);
		}
		return "instorage/instorageUpDispatch";
	}

	/**
	 * 进入分配主页
	 * @param taskId
	 * @param model
	 * @return String
	 */
	@RequestMapping(value = "toDispatchMain/{taskId}", method = RequestMethod.GET)
	public String toInstorageUpPage(@PathVariable("taskId") Long taskId, Model model) {
		try {
			InstorageUpDispatchTask task = this.instorageUpDispatchTaskService.findOne(taskId);
			model.addAttribute("task", task);
			List<InstorageUpDispatchSubTask> subTasks = instorageUpDispatchTaskService.findByTaskCode(task.getTaskCode());
			model.addAttribute("subTasks", subTasks);
			Map<String, List<InstorageUpSubTaskItem>> subItemMap = new HashMap<String, List<InstorageUpSubTaskItem>>();
			for (InstorageUpDispatchSubTask subTask : subTasks) {
				List<InstorageUpSubTaskItem> subItems = instorageUpDispatchTaskService.findBySubTaskCode(subTask.getSubTaskCode());
				subItemMap.put(subTask.getSubTaskCode(), subItems);
			}
			model.addAttribute("subItemMap", subItemMap);
			List<InstorageCountItem> unDispatch = instorageUpDispatchTaskService.unDispatchItem(task.getTaskCode());
			model.addAttribute("unDispatch", unDispatch);
		} catch (Exception e) {
			log.error("error.", e);
		}
		return "instorage/instorageDispatchTaskMain";

	}

	@RequestMapping(value = "loadSubDetail/{subTaskCode}", method = RequestMethod.POST)
	public void loadDetail(@PathVariable("subTaskCode") String subTaskCode, HttpServletResponse response) {
		try {
			List<InstorageUpSubTaskItem> subItems = instorageUpDispatchTaskService.findBySubTaskCode(subTaskCode);
			JSONObject json = new JSONObject();
			json.put("subItems", subItems);
			response.getWriter().print(json);
		} catch (Exception e) {
			log.error("error.", e);
		}
	}

	/**
	 * 领取分配的任务
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "ajaxTakeTask")
	@ResponseBody
	public String ajaxTakeTask(ServletRequest request, HttpServletResponse response) {
	    boolean isLockSuccess = false;
	    Long taskId = Long.valueOf(request.getParameter("taskId") + "");
		try {
		    isLockSuccess = workTaskService.lock("up..ajaxTakeTask", taskId+"", "-");
            if (!isLockSuccess) {
                return "false";
            }
            
			// 领取任务
			this.instorageUpDispatchTaskService.takeTask(taskId, getShiroUser().jobuuid);
			return "true";
		} catch (Exception e) {
			log.error("error", e);
			//update LiBin 20160829
			if (e instanceof PaiUException) {
			    return e.getMessage();
			}else {
			    return "false";
            }
		} finally {
            if (isLockSuccess) {
                workTaskService.releaseLock("up..ajaxTakeTask", taskId+"");
            }
        }
	}
	
	/**
	 * 开始分配前，验证状态
	 * 
	 * @param 
	 * @return 
	 * @throws 
	 * @author <a href=mailto:libin@nryuncang.com>libin</a>
	 * @version 1.0.0
	 */
	@RequestMapping(value = "ajaxDoDistribute")
    @ResponseBody
    public String ajaxDoDistribute(ServletRequest request, HttpServletResponse response) {
	    boolean isLockSuccess = false;
	    Long taskId=0L;
        try {
            taskId = Long.valueOf(request.getParameter("taskId") + "");
            isLockSuccess = workTaskService.lock("ajaxDoDistribute", taskId+"", "-");
            if (!isLockSuccess) {
                return "当前任务已在处理中，请勿重复处理！";
            }
            
            InstorageUpDispatchTask task = this.instorageUpDispatchTaskService.findOne(taskId);
            if ("2".equals(task.getStatus())) {
                return ErrorCode.REDO_INSTORAGE_UP_DISPATCH_TASK.getMessage(); 
            }

            return "true";
        } catch (Exception e) {
            log.error("error", e);
            return "网络繁忙，请稍后再试...";
        }finally {
            if (isLockSuccess) {
                workTaskService.releaseLock("ajaxDoDistribute", taskId+"");
            }
        }
    }

	/**
	 * 新增分配任务
	 * @param taskId
	 * @return String
	 */
	@RequestMapping(value = "createSubTask/{taskId}")
	public String create(@PathVariable("taskId") Long taskId) {
		try {
			InstorageUpDispatchTask task = this.instorageUpDispatchTaskService.findOne(taskId);
			// 创建子任务
			instorageUpDispatchTaskService.createSubTask(task.getTaskCode());
		} catch (Exception e) {
			log.error("error", e);
		}
		return "redirect:/v2_instorageUpDispatch/toDispatchMain/" + taskId;
	}

	/**
	 * 更新任务明细
	 * @param item void
	 */
	@RequestMapping(value = "updateSubDetail/{billCode}/{taskCode}/{subTaskCode}")
	@ResponseBody
	public String updateSubDetail(@RequestBody InstorageUpSubTaskItem[] item, @PathVariable("subTaskCode") String subTaskCode, @PathVariable("taskCode") String taskCode,@PathVariable("billCode") String billCode,ServletRequest request) {
	    boolean isLockSuccess = false;
        try {
            isLockSuccess = workTaskService.lock("up..updateSubDetail", taskCode, "-");
            if (!isLockSuccess) {
                return "false";
            }
            
            //add 20161025
            if (item == null || item.length == 0) {
                return "false";
            }
            
    	    //校验数量，避免出现负数量
    		boolean flag = instorageUpDispatchTaskService.checkNum(item,taskCode,billCode,subTaskCode) ; 
    		if(flag){
    			instorageUpDispatchTaskService.updateSubDetail(item, taskCode, subTaskCode);
    			return "true" ;
    		}else{
    			return "false" ;
    		}
        } finally {
            if (isLockSuccess) {
                workTaskService.releaseLock("up..updateSubDetail", taskCode);
            }
        }
	}
	/**
	 * 更新任务明细
	 * @param item void
	 */
	@RequestMapping(value = "updateSubDetail/{billCode}/{taskCode}")
	@ResponseBody
	public String updateSubDetail(@RequestBody InstorageUpSubTaskItem[] item,@PathVariable("taskCode") String taskCode,@PathVariable("billCode") String billCode,ServletRequest request) {
	    boolean isLockSuccess = false;
	    try {
	        isLockSuccess = workTaskService.lock("up..updateSubDetail", taskCode, "-");
	        if (!isLockSuccess) {
	            return "false";
	        }
	        
	        //add 20161025
            if (item == null || item.length == 0) {
                return "false";
            }
            
	        //校验数量，避免出现负数量
	        boolean flag = instorageUpDispatchTaskService.checkNum(item,taskCode,billCode,null) ; 
	        if(flag){
	            instorageUpDispatchTaskService.updateSubDetail(item, taskCode, null);
	            return "true" ;
	        }else{
	            return "false" ;
	        }
	    } finally {
	        if (isLockSuccess) {
                workTaskService.releaseLock("up..updateSubDetail", taskCode);
            }
	    }
		
	}

	/**
	 * 删除分配任务
	 * @param taskId
	 * @return String
	 */
	@RequestMapping(value = "delteteSubTask/{subTaskCode}/{taskId}")
	public String delteteSubTask(@PathVariable("subTaskCode") String subTaskCode, @PathVariable("taskId") Long taskId) {
		try {
			// 删除子任务
			instorageUpDispatchTaskService.deleteSubTask(subTaskCode);
		} catch (Exception e) {
			log.error("error", e);
		}
		return "redirect:/v2_instorageUpDispatch/toDispatchMain/" + taskId;
	}

	/**
	 * 完成任务分配
	 * @param taskId
	 * @return String
	 */
	@RequestMapping(value = "finishDispatchTask/{taskId}")
	public String finishDispatchTask(@PathVariable("taskId") Long taskId) {
		try {
			// 完成任务分配
			instorageUpDispatchTaskService.finishDispatchTask(taskId);
		} catch (Exception e) {
			log.error("error", e);
		}
		return "redirect:/v2_instorageUpDispatch/show";
	}
	/**
	 *批量 打印上架任务分配内容
	 * @param taskCode
	 * @param response void
	 */
	@RequestMapping(value = "ajaxBatchPrintUpTask", method = RequestMethod.POST)
	public void ajaxBatchPrintUpTask(@RequestParam(value = "taskCodes") String taskCodes, HttpServletResponse response) {
		PrintWriter out = null;
		JSONObject json = null;
		try {
			json = new JSONObject();
			out = response.getWriter();
			String[] taskCodeArr=taskCodes.split(":");
			Map<String,List<PrinterStyleType>> printerStyleTypes=new HashMap<String,List<PrinterStyleType>>();
			for(int i=0;i<taskCodeArr.length;i++){
				printerStyleTypes.put(taskCodeArr[i],instorageUpDispatchTaskService.printUpTask(taskCodeArr[i]));
				//更新printFlag字段标记为已打印
				InstorageUpDispatchTask instorageUpDispatchTask = instorageUpDispatchTaskDao.findByTaskCode(taskCodeArr[i]) ;
				Long bill_id = instorageUpDispatchTask.getInstorageBill().getId() ;
				InstorageBill instorageBill = instorageBillDao.loadBillById(bill_id) ; 
				String bill_code = instorageBill.getBillCode() ; 
				instorageBillService.updatePrintFlag("已", bill_code);
			}
			json.put("content", printerStyleTypes);
			json.put("status", "1");
			out.print(json.toString());
		} catch (Exception e) {

			json.put("status", "0");
			json.put("content", e.getMessage());
			out.print(json.toString());
			log.error("打印加载错误", e);
		}
	}
	
	
	/**
	 * 打印上架任务分配内容
	 * @param taskCode
	 * @param response void
	 */
	@RequestMapping(value = "ajaxPrintUpTask", method = RequestMethod.POST)
	public void ajaxPrintUpTask(@RequestParam(value = "taskCode") String taskCode, HttpServletResponse response) {
		PrintWriter out = null;
		JSONObject json = null;
		try {
			json = new JSONObject();
			out = response.getWriter();
			json.put("content", instorageUpDispatchTaskService.printUpTask(taskCode));
			json.put("status", "1");
			//更新printFlag字段标记为已打印
			InstorageUpDispatchTask instorageUpDispatchTask = instorageUpDispatchTaskDao.findByTaskCode(taskCode) ;
			Long bill_id = instorageUpDispatchTask.getInstorageBill().getId() ;
			InstorageBill instorageBill = instorageBillDao.loadBillById(bill_id) ; 
			String bill_code = instorageBill.getBillCode() ; 
			instorageBillService.updatePrintFlag("已", bill_code);
			out.print(json.toString());
		} catch (Exception e) {

			json.put("status", "0");
			json.put("content", e.getMessage());
			out.print(json.toString());
			log.error("打印加载错误", e);
		}
	}
	
	
	/**
	 * 入库日志明细
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "v2_instorageLog/{billCode}")
	public String instorageLog(@PathVariable("billCode") String billCode,Model model) {
		try {
			List<InstorageLog> logList = instorageLogDao.loadLogByBillCode(billCode);
			model.addAttribute("logList",logList);
		} catch (Exception e) {
			logger.error("error",e);
		}
		return "instorage/instorageLog";
	}
	
	@RequestMapping(value = "printUpTaskPage",method=RequestMethod.POST)
	public void printUpTaskPage(ServletRequest request,HttpServletResponse response) {
		JSONObject json = null;
		PrintWriter out = null;
		try {
				json = new JSONObject();
				out = response.getWriter();
				String billCode=request.getParameter("billCode");
				String printType=request.getParameter("printType");
				String billType=request.getParameter("billType");
				json.put("status", "success");
				if(StringUtils.equals(printType, "1")){//打印验收单
					json.put("instorageBillItemYSList",instorageBillService.printTaskPageForYS(billCode,billType));
					instorageBillService.updateInstorageBillPrintYsNum(billCode);
				}else if(StringUtils.equals(printType, "2")){//打印上架单
					json.put("instorageBillItemSJList",instorageBillService.printUpTaskPageForUp(billCode));
					instorageBillService.updateInstorageBillPrintSjNum(billCode);
				}
				json.put("receiptDate",instorageBillService.getCountTaskDateByBillCode(billCode).isEmpty()? "":instorageBillService.getCountTaskDateByBillCode(billCode));
				json.put("instorageBill", instorageBillService.loadBillByCode(billCode));

		} catch (Exception e) {
			logger.error("error",e);
			json.put("status","error");
			json.put("content",e.getMessage());
		}
		out.print(json.toString());
	}
	
}
